package com.daxia.bumall.web.controller;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Vector;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.daxia.bumall.basemodel.CoreUser;
import com.daxia.bumall.common.PayBizType;
import com.daxia.bumall.common.PayStatus;
import com.daxia.bumall.common.PayType;
import com.daxia.bumall.common.SmsSendType;
import com.daxia.bumall.dto.AddressDTO;
import com.daxia.bumall.dto.CartDTO;
import com.daxia.bumall.dto.FactoryInfoDTO;
import com.daxia.bumall.dto.OrderDTO;
import com.daxia.bumall.dto.UserCartDTO;
import com.daxia.bumall.dto.UserDTO;
import com.daxia.bumall.model.OrderItem;
import com.daxia.bumall.model.Specification;
import com.daxia.bumall.model.User;
import com.daxia.bumall.util.SmsService;
import com.daxia.bumall.util.SpringSecurityUtils;
import com.daxia.bumall.util.ValidationUtils;

@Controller
@RequestMapping("order")
public class OrderController extends BaseController {
	
	/**
	 * 将结算的信息生成订单,从购物车结算页面过来，主要包含两步，第一步，将购物车信息取出并生成订单，第二步，转入支付
	 * 此处的订单信息，以用户选择的商品从属的各工厂来进行多个订单划分，然后各个订单下面，又分为子订单，即各商品的结算信息
	 * @param cartList  结算页面中确认结算的购物信息，包括商品，类型，数量等信息
	 * @param addressId  收货地址id，从页面传过来
	 * @param totalPay   应付总数
	 * @param payType    支付类型
	 * @param remark     订单备注
	 * @param invoiceType   发票信息
	 * @param map       
	 * @return
	 */
	@Transactional
	@ResponseBody
    @RequestMapping(value = "/checkoutOrder")
	public String checkoutOrder(String cartInfo,Long addressId,Double totalPay,Integer payType,
			String remark,Integer invoiceType,Map<String, Object> map) throws Exception {  
		CoreUser currentUser = SpringSecurityUtils.getCurrentUser();
    	ValidationUtils.assertTrue(currentUser != null, "您还没有登陆，不能是用结算和支付功能!"); 
    	ValidationUtils.assertTrue(StringUtils.isNotBlank(cartInfo), "请选择商品进行支付!");
    	ValidationUtils.assertTrue(addressId != null, "请选择收货地址!");
    	ValidationUtils.assertTrue(totalPay != null, "请确认支付金额!");
    	ValidationUtils.assertTrue(payType != null, "请选择支付方式!");
    	
		List<CartDTO> carts = seprateCartFromStr(cartInfo);   //拆分前台传过来的购物支付信息
		AddressDTO address = new AddressDTO();    //地址信息
		address.setId(addressId);
		address = addressService.findOne(address);
		UserDTO user = new UserDTO();    //用户信息
		user.setId(currentUser.getId());
		user = userService.findOne(user);
		List<UserCartDTO> userCarts = manageUserCart(carts);   //将购物信息通过商品工厂和用户进行区分从而形成不同的订单
		Long[] deleteIds = new Long[carts.size()];    //在从购物车到订单之后，将购物车中已经选择支付的从购物车中进行删除操作
		int index = 0;
		Long orderId = null;
		List<OrderDTO> orders = new Vector<OrderDTO>();
		for(UserCartDTO userCart:userCarts) {   //分割订单和子订单
			//主订单部分，包括地址、支付方式，用户等
			OrderDTO order = new OrderDTO();
			order.setUser(user);
			order.setFactoryUser(userCart.getUser());
			order.setReceiveName(address.getName());
			order.setReceiveMobile(address.getMobile());
			order.setProvince(address.getProvince());
			order.setCity(address.getCity());
			order.setDistrict(address.getDistrict());
			order.setAddress(address.getAddress());
			order.setCreateTime(new Date());
			order.setPayType(payType);
			order.setInvoiceType(invoiceType);
			order.setPayStatus(PayStatus.NotPay.getValue());
			order.setInvoiceType(invoiceType);
			order.setOrderNo(generatePaymentNo(PayBizType.Buy.getValue()));
			
			List<OrderItem> items = new Vector<OrderItem>();
			Double allCount = 0d;
			double singleTotalAmount = 0d;
			for(CartDTO theCart:userCart.getCartList()) {   //将各个选定商品都生成一条orderitem对象
				OrderItem aItem = new OrderItem();
				aItem.setProduct(theCart.getProduct());
				aItem.setQuantity(theCart.getQuantity());
				Specification specification = theCart.getSpecification();
				aItem.setSpecification(specification);
				Double itemCount = specification.getRealPrice()*theCart.getQuantity();
				aItem.setPayPrice(itemCount);
				aItem.setSellingPrice(specification.getSellingPrice());
				aItem.setFactor(specification.getFactor());
				singleTotalAmount += aItem.getSellingPrice();
				allCount += itemCount;
				deleteIds[index ++ ] = theCart.getId();
				items.add(aItem);
			}
			order.setAmount(new BigDecimal(singleTotalAmount));
			order.setOrderItems(items);
			orderId = orderService.createOrderAndItem(order);
			order.setId(orderId);
			orders.add(order);
		}
		String orderIds = "";
		if(orders.size() > 1) {
			orderId = null;
			for(OrderDTO orderDTO:orders) {
				orderIds += orderDTO.getId() + ",";
			}
		}
		cartService.deleteByIds(deleteIds);   //把已经生成订单的商品从购物车中移除
		if(payType == PayType.offLine.getValue()) {   //线下付款，发送短信给用户
			String mobile = user.getMobile();
			SmsService.sendWithTemplate(mobile, SmsSendType.offLineRemind.getValue(), new HashMap<String,Object>());
		}
		JSONObject jObj = new JSONObject();
		jObj.put("success", true);
		jObj.put("orderId", orderId);
		jObj.put("payType", payType);
		jObj.put("amount", totalPay);
		jObj.put("orderIds", orderIds);
		jObj.put("userId", currentUser.getId());
		jObj.put("payBizType", PayBizType.Buy.getValue());
    	return jObj.toJSONString();
    }
	
	private String generatePaymentNo(Integer payType) {
		String no = "OR";
		no += payType;
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		no += dateFormat.format(new Date());
		no += (1000 + new Random().nextInt(8999));
		return no;
	}
	
	public List<UserCartDTO> manageUserCart(List<CartDTO> cartList) {   //将同一厂家的放在一个里面
		List<CartDTO> copyList = new Vector<CartDTO>(cartList);
		List<UserCartDTO> list = new Vector<UserCartDTO>(); 
		if(copyList != null && copyList.size() > 0) {
			while(copyList.size() > 0) {   //遍历list,找出所有商店数据并整理，直到所有子产品都被分出来
				CartDTO firstCart = copyList.get(0);   //得到第一个购物车信息，并拿出对应的厂家信息
				User proUser = firstCart.getProduct().getUser();
				copyList.remove(0);   //去掉第一个
				if(proUser != null) {   //未知用户，没有关联到，直接干掉
					UserCartDTO userCart = new UserCartDTO();
					userCart.setUser(proUser);
					FactoryInfoDTO factoryInfo = factoryInfoService.findFactoryByUserId(proUser.getId());
					userCart.setCartList(new Vector<CartDTO>());
					userCart.setFactory(factoryInfo);    //把对应的工厂信息也加进去
					userCart.getCartList().add(firstCart);
					for(int i = copyList.size() - 1;i >= 0;i -- ) {   //从后往前遍历,删掉同一个商店的购物信息，并加入到商铺购物车中
						CartDTO theCart = copyList.get(i);
						User theUser = theCart.getProduct().getUser();
						if(theUser != null) {
							if(proUser.getId().longValue() == theUser.getId().longValue()) {   //相同就加入
								userCart.getCartList().add(1,theCart);   //每次遍历到的都放到第二位
								copyList.remove(i);   //然后再删除掉
							}
						}
					}
					list.add(userCart);
				}
			}
		}
		return list;
	}
	
	public List<CartDTO> seprateCartFromStr(String str) {  //将购物车结算信息从字符串中分隔开来，形式如：1-3,2-5,
		List<CartDTO> dtos = new Vector<CartDTO>();
		String[] split = str.split(",");
		for(String aSplit:split) {
			if(aSplit != null && !"".equals(aSplit)) {
				String[] info = aSplit.split("-");
				CartDTO adto = new CartDTO();
				adto.setId(Long.parseLong(info[0]));
				adto = cartService.findOne(adto);   //从库里把购物车信息查出来，然后将数量进行改正
				adto.setQuantity(Integer.parseInt(info[1]));
				dtos.add(adto);
 			}
		}
		return dtos;
	}
}